﻿using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UMLSynthesizer.CSharpAnalyzer.Elements;
using UMLSynthesizer.CSharpAnalyzer.Expressions;
using UMLSynthesizer.CSharpAnalyzer.Helpers;
using UMLSynthesizer.LangAnalyzer.Elements;
using UMLSynthesizer.LangAnalyzer.Expressions;
using UMLSynthesizer.LangAnalyzer.Statements;

namespace UMLSynthesizer.CSharpAnalyzer.Statements
{
    class CSharpLocalDeclarationStatement : CSharpStatementBase, ILocalDeclarationStatement
    {
        #region Fields

        VariableDeclarationSyntax declaration;
        CSharpExpressionHelper initializerExprHelper;
        IEnumerable<KeyValuePair<string, IExpressionBase>> _variableInitializerExpressions;

        #endregion

        #region Constructor

        public CSharpLocalDeclarationStatement(LocalDeclarationStatementSyntax statementNode, IStatementBase parentStatement)
            : base(statementNode, parentStatement, null, StatementKinds.LocalDeclaration)
        {
            this.declaration = statementNode.Declaration;
            initializerExprHelper = new CSharpExpressionHelper(null, this);
        }
        public CSharpLocalDeclarationStatement(VariableDeclarationSyntax variableDeclarationSyntax, IStatementBase parentStatement)
            : base(null, parentStatement, null, StatementKinds.LocalDeclaration)
        {
            this.declaration = variableDeclarationSyntax;
            initializerExprHelper = new CSharpExpressionHelper(null, this);
        }

        #endregion

        #region Properties

        public ITypeBase Type
        {
            get
            {
                if (declaration != null)
                    return (ProjectOwner as CSharpProjectElement).GetTypeReference(declaration.Type);
                else
                    return null;
            }
        }
        public IEnumerable<ITypeBase> TypeArgumentList
        {
            get
            {
                if (declaration != null && declaration.Type as GenericNameSyntax != null)
                    return from argument in (declaration.Type as GenericNameSyntax).TypeArgumentList.Arguments
                           select (ProjectOwner as CSharpProjectElement).GetTypeReference(argument);
                return new ITypeBase[0];
            }
        }
        public IEnumerable<string> VariableIdentifiers
        {
            get
            {
                if (declaration != null)
                    return from variable in declaration.Variables
                           select variable.Identifier.ToString();
                return new string[0];
            }
        }
        public IEnumerable<KeyValuePair<string, IExpressionBase>> VariableInitializerExpressions
        {
            get
            {
                if (_variableInitializerExpressions == null)
                {
                    if (declaration != null)
                        _variableInitializerExpressions = new List<KeyValuePair<string, IExpressionBase>>(
                            from variable in
                                (from variable in declaration.Variables
                                 where variable.Initializer != null
                                 select variable)
                            select new KeyValuePair<string, IExpressionBase>(variable.Identifier.ToString(),
                                initializerExprHelper.CreateCSharpExpression(variable.Initializer.Value)));
                    else
                        return new KeyValuePair<string, IExpressionBase>[0];
                }
                return _variableInitializerExpressions;
            }
        }

        #endregion
    }
}
